package com.duang.framework.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletContext;

import com.duang.framework.cache.CacheProvider;
import com.duang.framework.core.LifeCycle;

public class SystemConfiguration implements LifeCycle, ConfigureProcess {

	private static SystemConfiguration config;
	private Properties properties;
	private static ServletContext servletContext;
	private AbstractConfiguration applicationConfig;
	private boolean isStart;

	public static final String APP_CONFIG_PATH = "app.config.class.path";

	public static void setConfig(SystemConfiguration config) {
		SystemConfiguration.config = config;

	}

	public void init(String configPath) throws IOException {
		InputStream stream = SystemConfiguration.class.getClassLoader()
				.getResourceAsStream(configPath);
		properties = new Properties();
		properties.load(stream);
	}

	public void start() throws ConfigureApplicationException {
		try {
			String path;
			if ((path = System.getProperty(APP_CONFIG_PATH)) == null) {
				path = "duang.properties";
			}
			this.init(path);
		} catch (IOException e) {
			throw new ConfigureApplicationException(e);
		}
	}

	public final static AbstractConfiguration getAppConfig() {

		return config.applicationConfig;
	}

	public static CacheProvider getCacheProvider() {
		return config.applicationConfig.getCacheProvider();

	}

	
	
	public final static boolean isDedug() {

		return config.applicationConfig.isDedug();
	}

	public static boolean useCache() {

		return config.applicationConfig.useCache();
	}

	@Override
	public void destroy() {
		config.applicationConfig.stopPlugins();
	}

	@Override
	public void configure() {
		if (isStart)
			return;
		String appConfigPath = properties.getProperty(APP_CONFIG_PATH);
		Class<?> clazz;
		try {
			clazz = this.getClass().getClassLoader().loadClass(appConfigPath);
			if (!AbstractConfiguration.class.isAssignableFrom(clazz)) {
				throw new ConfigureApplicationException(
						"config class must extend com.duang.framework.config.AbstractAppConfig");
			}
			applicationConfig = (AbstractConfiguration) clazz.newInstance();
			applicationConfig.start();
			applicationConfig.configure();
			applicationConfig.end();
		} catch (ClassNotFoundException e) {
			throw new ConfigureApplicationException(e);
		} catch (InstantiationException e) {
			throw new ConfigureApplicationException(e);
		} catch (IllegalAccessException e) {
			throw new ConfigureApplicationException(e);
		}
		isStart = true;
		this.applicationConfig.startPlugins();
		if (config != this)
			config = this;
	}
	
	public static final ServletContext getServletContext(){
		return servletContext;
	}

	@Override
	public void end() {

	}

	public static void init(ServletContext servletContext) {
	          SystemConfiguration.servletContext = servletContext;
		
	}

}
